package com.psychologyCommunity.Community.service;

import com.psychologyCommunity.Community.dao.DiscussPostMapper;
import com.psychologyCommunity.Community.dao.UserMapper;
import com.psychologyCommunity.Community.entity.DiscussPost;
import com.psychologyCommunity.Community.entity.User;
import com.psychologyCommunity.Community.util.CommunityUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Date;

@Service
public class AlphaService {
        //service依赖Dao的方式
//       @Autowired
//       private AlphaDao alphaDao;
//       public String find(){
//           return  alphaDao.select();
//       }

       public AlphaService(){
           System.out.println("实例化AlphaService方法");
       }

       @PostConstruct  //创建构造器之后
        public void init(){
            System.out.println("初始化AlphaService");
        }

        @PreDestroy  //在对象销毁之前调用它 ，否则销毁了 这个对象都没了 怎么调用
        public void destroy(){
            System.out.println("销毁AlphaService");
        }


        //关于两种事务的演示小demo
    @Autowired
    private UserMapper userMapper;

       @Autowired
    private DiscussPostMapper discussPostMapper;

       //通过注解的方式来增加管理
    //REQUIRED 支持当前事务(外部事物) ，如果外部事物不存在则创建新事务；假设A调用我，A有事务，就按A的来，如果A没有事务，我就创建一个新的事务按这个来
    //REQUIRES_NEW:创建一个新事务，并且暂停当前事务(外部事务);A调用B，B无视A的事务，B永远创建一个新事务按照新事务执行
    //NESTED：如果当前存在事务（外部事务），则嵌套在该事物中执行（有独立的提交和回滚）；如果-外部事务不存在，就和REQUIRES_NEW一样 例如：A调B，A有事务，B在执行时就嵌套在A的事务中执行
     @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
       public Object Save(){
           //新增用户
           User user=new User();
           user.setUsername("LOCO");
           user.setSalt(CommunityUtil.generateUUID().substring(0,5));
           user.setPassword(CommunityUtil.md5("123456"+user.getSalt()));
           user.setCreateTime(new Date());
           user.setEmail("HUBU@163.com");
           user.setHeaderUrl("http://images.nowcoder.com/head/777t.png");
           userMapper.insertUser(user);

           //新增帖子
           DiscussPost post=new DiscussPost();
           post.setUser_id(user.getId());
           post.setTitle("Nothing");
           post.setContent("新专辑");
           post.setCreateTime(new Date());
           discussPostMapper.insertDiscussPost(post);

           Integer.valueOf("abc");//制造一个错误 “abc”转为整数，肯定会报错
           return "okk";

       }
    //这个bean是spring自动创建，自动装配到容器中的，注入就能直接用
    //利用这个bean 来执行 sql 就可以保证ACID
        @Autowired
      private   TransactionTemplate transactionTemplate;
    public Object Save2(){
         transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
         transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
         //利用它去执行sql
        return transactionTemplate.execute(new TransactionCallback<Object>() {
            @Override
            public Object doInTransaction(TransactionStatus status) {
                //这个方法是由transactionTemplate去调用的 ，但是这个逻辑是我们自己实现的
                //新增用户
                User user=new User();
                user.setUsername("LOCO2");
                user.setSalt(CommunityUtil.generateUUID().substring(0,5));
                user.setPassword(CommunityUtil.md5("12345"+user.getSalt()));
                user.setCreateTime(new Date());
                user.setEmail("HUBU22@163.com");
                user.setHeaderUrl("http://images.nowcoder.com/head/47t.png");
                userMapper.insertUser(user);
                //新增帖子
                DiscussPost post=new DiscussPost();
                post.setUser_id(user.getId());
                post.setTitle("Nothing——plus");
                post.setContent("新专辑升级版");
                post.setCreateTime(new Date());
                discussPostMapper.insertDiscussPost(post);
                Integer.valueOf("abc");//制造一个错误 “abc”转为整数，肯定会报错
                return "okk";
            }
        });
    }

    private static final Logger logger= LoggerFactory.getLogger(AlphaService.class);
    //@Async让该方法 在多线程环境下，被异步的调用
//    @Async
//    public void execute(){//相当于一个线程体  --相当于一个任务
//        logger.debug("executel 简化版的Spring");
//    }

    //定时任务 ，服务器已启动 触发就会运行 打印，太乱了 注销
    //initialDelay希望延迟多久执行，fixedDelay固定1s执行一次
//   @Scheduled(initialDelay = 10000,fixedDelay =1000)
//    public void execute2(){//相当于一个线程体  --相当于一个任务
//        logger.debug("execute2 Spring定时任务线程池");
//    }
}
